package com.example.meeting.service.impl;

import com.example.meeting.mapper.AdminMapper;
import com.example.meeting.mapper.PersonMapper;
import com.example.meeting.model.domain.Admin;
import com.example.meeting.model.responseData.CommonResult;
import com.example.meeting.service.IAdminService;
import com.example.meeting.utils.RedisUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class AdminServiceImpl implements IAdminService {
    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private PersonMapper personMapper;

    @Override
    public Admin selectAdminById(Long id) {
        try {
            return adminMapper.selectAdminById(id);
        } catch (Exception e){
            log.error("查询管理员接口报错！{}",e.getMessage());
        }
        return null;
    }

    @Override
    public PageInfo<Admin> selectAdminList(Integer page,Integer pageSize,Admin admin) {
        try {
            PageHelper.startPage(page,pageSize);
            List<Admin> adminList = adminMapper.selectAdminList(admin);
            return new PageInfo<>(adminList);
        } catch (Exception e){
            log.error("查询管理员列表接口报错！{}",e.getMessage());
        }
        return null;
    }

    @Override
    public Integer addAdmin(Admin admin) {
        try {
            //加密算法对密码进行加密
            String password = bCryptPasswordEncoder.encode(admin.getPassword());
            admin.setPassword(password);
            log.info("新增用户：{}",admin.getUsername());

            Integer res = adminMapper.addAdmin(admin);
            //根据admin扩展到person
            personMapper.addPersonByAdmin(res,admin.getUsername());

            return res;
        } catch (Exception e){
            log.error("新增用户接口报错！{}",e.getMessage());
        }
        return 0;
    }

    @Override
    public Integer updateAdmin(Admin admin) {
        try {
            //获取id
            Long id = admin.getId();
            //根据id查询数据库中对应的数据
            Admin dataAdmin = adminMapper.selectAdminById(id);
            //判断前端传过来的密码是否与数据库的加密密码相同,不同则需修改
            boolean flag = false;
            if (!dataAdmin.getPassword().equals(admin.getPassword())){
                //设置新的加密密码
                admin.setPassword(bCryptPasswordEncoder.encode(admin.getPassword()));
                flag = true;
            }
            Integer res = adminMapper.updateAdmin(admin);
            if (res == 0) {
                return 0;
            }
            //如果修改了密码，则清除对应管理员的会话缓存
            if (flag){
                //删除自定义的当前用户会话信息
                RedisUtil.remove(admin.getUsername());
                //删除自定义的当前用户token信息
                if (RedisUtil.hasKey(admin.getUsername()+"_token")){
                    //删除自定义的当前用户token信息
                    Boolean isRemove = RedisUtil.remove(admin.getUsername() + "_token");
                    log.info("更新管理员信息。删除用户名为【"+admin.getUsername()+"】的会话缓存:"+isRemove);
                }
            }
            log.info("修改 "+"{}"+" 管理员密码",admin.getUsername());
            return res;
        } catch (Exception e){
            log.error("更新管理员接口报错！{}",e.getMessage());
        }
        return 0;
    }

    @Override
    public CommonResult deleteAdmin(Long id) {
        try {
            //获取当前会话，判断登录的Id和前端传入的Id是否一样
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession();
            if (session.getAttribute("username") != null) {
                Admin adminExist = adminMapper.authenticationByUsername(String.valueOf(session.getAttribute("username")));
                if (!id.equals(adminExist.getId())) {
                    return CommonResult.fail("禁止删除他人账号！");
                }
            }
            Integer res = adminMapper.deleteAdmin(id);
            if (res == 0){
                return CommonResult.fail("删除管理员失败！");
            }
            return CommonResult.success(res);
        } catch (Exception e){
            log.error("删除管理员接口报错！{}",e.getMessage());
        }
        return CommonResult.fail();
    }

    @Override
    public CommonResult updateAdminPassword(String jsonStr) {
        try {
            JSONObject jsonObject = new JSONObject(jsonStr);
            Long id = jsonObject.getLong("id");
            //获取当前会话，判断登录的Id和前端传入的Id是否一样
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession();
            if (session.getAttribute("username") != null) {
                Admin adminExist = adminMapper.authenticationByUsername(String.valueOf(session.getAttribute("username")));
                if (!id.equals(adminExist.getId())) {
                    return CommonResult.fail("禁止修改他人密码！");
                }
            }
            Admin dataAdmin = adminMapper.selectAdminById(id);
            if (dataAdmin == null) {
                return CommonResult.fail("该管理员不存在，无法修改！");
            }
            //判断用户输入的原密码和查询到的数据库中的加密密码是否匹配
            boolean matches = bCryptPasswordEncoder.matches(jsonObject.getString("oldPwd"), dataAdmin.getPassword());
            //如果匹配则修改数据库中的密码，不匹配则返回错误提示信息
            if (!matches){
                return CommonResult.fail("原密码错误，请重试！");
            }
            //把要更新的数据封装为一个Admin对象
            Admin admin = new Admin();
            admin.setId(dataAdmin.getId());
            admin.setPassword(bCryptPasswordEncoder.encode(jsonObject.getString("newPwd")));
            Integer res = adminMapper.updateAdmin(admin);
            if (res == 0) {
                return CommonResult.fail("修改密码失败!");
            }
            log.info("修改id："+id+" 用户名："+dataAdmin.getUsername()+"的密码");
            return CommonResult.success(res);
        } catch (Exception e){
            log.error("修改管理员密码接口报错！{}",e.getMessage());
        }
        return CommonResult.fail();
    }

    @Override
    public Admin authenticationByUsername(String username) {
        try{
            return adminMapper.authenticationByUsername(username);
        }catch (Exception e){
            log.error("根据用户名查询管理员接口出错,"+e.getMessage());
        }
        return null;
    }
}
